<?php

namespace app\helpers;

//use think\facade\Db;

/**
 * Class Common Helper
 * @package App\Helpers
 */
class Common
{
    /**
     * Explodes a string and trims all values for whitespace in the end.
     * If $onlyNonEmptyValues is set, then all blank ('') values are removed.
     *
     * @param string $delim Delimiter string to explode with
     * @param string $string The string to explode
     * @param bool $removeEmptyValues If set, all empty values will be removed in output
     * @param int $limit If limit is set and positive, the returned array will contain a maximum of limit elements with
     *                   the last element containing the rest of string. If the limit parameter is negative, all components
     *                   except the last -limit are returned.
     * @return array Exploded values
     */
    public static function trimExplode($delim, $string, $removeEmptyValues = false, $limit = 0)
    {
        $result = explode($delim, $string);
        if ($removeEmptyValues) {
            $temp = array();
            foreach ($result as $value) {
                if (trim($value) !== '') {
                    $temp[] = $value;
                }
            }
            $result = $temp;
        }
        if ($limit > 0 && count($result) > $limit) {
            $lastElements = array_splice($result, $limit - 1);
            $result[] = implode($delim, $lastElements);
        } elseif ($limit < 0) {
            $result = array_slice($result, 0, $limit);
        }
        $result = array_map('trim', $result);

        return $result;
    }

    /**
     * Generate tree options
     *
     * @param object $model
     * @param array $where
     * @param array $orderBy
     * @param array $defaultOptions
     * @param int $id
     * @param string $titleField
     * @param string $parentField
     * @return array
     */
    public static function makeTreeOptions($model, $where = [], $orderBy = [], $defaultOptions = [], $id = 0, $titleField = 'title', $parentField = 'parent_id')
    {
        $options = [];
        if (!empty($defaultOptions)) {
            $options = $defaultOptions;
        }
        $recursive = function ($id, $level) use (&$recursive, $model, $where, $orderBy, &$options, $titleField, $parentField) {
            $space = '';
            for ($i = 0; $i < $level; $i++) {
                $space .= '&nbsp;&nbsp;';
            }
            if ($level) $space .= '&nbsp;&nbsp;├&nbsp;';

            $model = $model::where(array_merge([[$parentField, '=', $id]], $where));
            if (!empty($orderBy)) {
                foreach ($orderBy as $key => $val) {
                    $model = $model->order($key, $val);
                }
            }

            $results = $model->select();
            foreach ($results as $result) {
                $options[$result->id] = $result->id . '. ' . $space . $result->{$titleField};
                $recursive($result->id, $level + 1);
            }
        };
        $recursive($id, 0);

        return $options;
    }

    /**
     * Generate options
     *
     * @param $model
     * @param array $where
     * @param array $orderBy
     * @param array $defaultOptions
     * @param string $keyField
     * @param string $titleField
     * @param string $sep
     * @return array
     */
    public static function makeOptions($model, $where = [], $orderBy = [], $defaultOptions = [], $keyField = 'id', $titleField = 'title', $sep = '-')
    {
        $options = [];
        if (!empty($defaultOptions)) {
            $options = $defaultOptions;
        }
        $model = $model::where($where);
        if (!empty($orderBy)) {
            foreach ($orderBy as $key => $val) {
                $model = $model->order($key, $val);
            }
        }
        $results = $model->select();
        $tempTitle = [];
        if (is_array($titleField)) {
            $tempTitle = $titleField;
        } else {
            array_push($tempTitle, $titleField);
        }
        foreach ($results as $result) {
            $titleValue = [];
            foreach ($tempTitle as $field) {
                if ($result->{$field}) {
                    array_push($titleValue, $result->{$field});
                }
            }
            $options[$result->{$keyField}] = implode(' ' . $sep . ' ', $titleValue);
        }

        return $options;
    }

    /**
     * Generate tree options (包含所有字段)
     *
     * @param $model
     * @param array $where
     * @param array $orderBy
     * @param int $id
     * @param string $titleField
     * @param string $parentField
     * @param bool $useSpace
     * @return array
     */
    public static function getTreeList($model, $where = [], $orderBy = [], $id = 0, $titleField = 'title', $parentField = 'parent_id', $useSpace = false)
    {
        $options = [];
        $recursive = function ($id, $level) use (&$recursive, $model, $where, $orderBy, &$options, $titleField, $parentField, $useSpace) {
            $newModel = $model::where(array_merge([[$parentField, '=', $id]], $where));
            if (!empty($orderBy)) {
                foreach ($orderBy as $key => $val) {
                    $newModel = $newModel->order($key, $val);
                }
            }

            $results = $newModel->select();
            foreach ($results as $result) {
                if ($useSpace) {
                    $space = '';
                    for ($i = 1; $i < $level; $i++) {
                        //$space .= '&nbsp;&nbsp;';
                        $space .= '&nbsp;│&nbsp;';
                    }
                    if ($level > 1) {
                        $space .= '&nbsp;├─&nbsp;';
                    }
                    $result->$titleField = $space . $result->$titleField;
                }

                if ($model::where(array_merge([[$parentField, '=', $result->id]], $where))->count()) {
                    $result->has_children = 1;
                }
                $result->level = $level;
                $options[$result->id] = $result;
                $recursive($result->id, $level + 1);
            }
        };

        $recursive($id, 1);

        return $options;
    }

    /**
     * 加密&解密
     *
     * @param string $password 密码
     * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE表示解密，其它表示加密ENCODE
     * @return false|string
     */
    public static function passwordEncrypt($password, $operation = 'DECODE')
    {
        $des = new \app\libs\Des();
        if ($operation == 'DECODE') {
            return $des->decrypt($password);
        } else {
            return $des->encrypt($password);
        }
    }

    /**
     * 操作日志
     *
     * @param $request
     * @param int|string $adminId
     * @param string $content
     * @param int|string $relatedId
     * @param string $info
     */
    public static function actionLog($request, $adminId, $content, $relatedId, $info = '')
    {
        $model = new \app\common\model\AdminLog();
        $data = [
            'created_at' => time(),
            'created_id' => $adminId,
            'content' => $content,
            'ip' => get_IP(),
            'url' => app('http')->getName() . '/' . $request->pathinfo(),
            'related_id' => $relatedId,
            'info' => $info
        ];
        //$model->create($data);
        return $model->insert($data);
    }

    /**
     * CURL请求
     *
     * @param string $url 请求url地址
     * @param string $method 请求方法 get post
     * @param null $params 参数
     * @param array $headers 请求header信息
     * @return mixed
     */
    public static function curlRequest($url, $method, $params = null, $headers = [])
    {
        $method = strtoupper($method);
        $ci = curl_init();
        curl_setopt($ci, CURLOPT_URL, $url); // 要访问的地址
        switch ($method) {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, true); // 发送一个常规的Post请求
                if (!empty($params)) {
                    $tmpDataStr = is_array($params) ? http_build_query($params) : $params;
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpDataStr); // Post提交的数据包
                }
                break;
            default:
                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); // 设置请求方式
                break;
        }
        $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
        if ($ssl) {
            curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
        }
        if (!empty($headers)) {
            curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($ci, CURLOPT_TIMEOUT, 60); // 设置cURL允许执行的最长秒数
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 0); // 在尝试连接时等待的秒数。设置为0，则无限等待。
        curl_setopt($ci, CURLOPT_HEADER, false); // 启用时会将头文件的信息作为数据流输出
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);  // 获取的信息以文件流的形式返回
        curl_setopt($ci, CURLINFO_HEADER_OUT, true); // true 时追踪句柄的请求字符串

        $response = curl_exec($ci);
        //$requestInfo = curl_getinfo($ci);
        $req_errno = curl_errno($ci);
        if ($req_errno) {
            log_info("---> Curl Request error: " . json_encode($req_errno, JSON_UNESCAPED_UNICODE), 'INFO', 'curl_request');
        }
        curl_close($ci);

        //return $response;
        return json_decode($response, true);
    }
}
